import { http } from '@/utils/http'
import { FileInfo, ConditionSelectorParams } from '@/types/modules/file-info'
import { BasicPageParams } from '@/types'
import axios, { CancelTokenSource } from "axios";
import { useLoginAccountStoreWithOut } from '@/store/modules/login'
import { ref } from 'vue';

const CancelToken = axios.CancelToken;  
const tokenSource = ref<CancelTokenSource>()

tokenSource.value = CancelToken.source();

export interface FileChunk {
  filename: string,
  chunks: Chunk[],
  hash: string
}

export interface Chunk {
  Index: number,
  Data: Blob
}

export enum UploadStatus {
  None = 0,
  Uploading = 1,
  Pause = 2,
  Hashing = 3,
}

const loginStore = useLoginAccountStoreWithOut();

export const getConditionSelector = (params: BasicPageParams & ConditionSelectorParams) => {
  return http.request<FileInfo>('get', '/api/file-info/condition-selector', {
    params
  })
}

const service = axios.create({
  baseURL: 'https://172.25.13.69:7235',
  timeout: 2160000,
  withCredentials: false,
  headers: {
    'Content-Type': 'multipart/form-data'
  }
});

export const uploadChunk = async (formData: FormData, callback?: Function) => {    
  return await service.post('/api/file-info/chunk', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      'Authorization': `Bearer ${loginStore.getToken}`
    },
    cancelToken: tokenSource.value?.token
  }).then(() => {    
    callback && callback()
  })
}

export const mergeChunk = async (identifier: string, filename: string) => {   
  return await service.post('/api/file-info/merge', null, {
    headers: {      
      'Authorization': `Bearer ${loginStore.getToken}`,
      'X-Chunk-Identifier': identifier,
      'X-Chunk-Filename': encodeURIComponent(filename)
    }
  })
}

export const getChunkSlices = (identifier: string) => {
  return service.get('/api/file-info/slice', {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${loginStore.getToken}`,
      'X-Chunk-Identifier': identifier
    }
  })
}

export const verifChunk = (identifier: string, index: number) => {
  return service.get('/api/file-info/verify', {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${loginStore.getToken}`,
      'X-Chunk-Identifier': identifier,
      'X-Chunk-Index': index
    }
  })
}

export const cancelUpload = () => {
  tokenSource.value?.cancel('停止上传')

  tokenSource.value = CancelToken.source();
}

export const upload = (formData: any, callback: Function) => {
  return service.post('/api/file-info', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      'Authorization': `Bearer ${loginStore.getToken}`
    },
    onUploadProgress: ev => {
      callback && callback(ev.loaded / ev.total * 100 | 0);
    }
  })  
}

export const download = (fileInfo: FileInfo, callback: Function) => { 
  return service.get(fileInfo.url as string, {
    baseURL: undefined,
    responseType: 'blob',
    onDownloadProgress: ev => {      
      if (ev.lengthComputable) {
        callback && callback(ev.loaded / ev.total * 100 | 0);
      }
    }
  })
}

export const updateFileInfo = (data: FileInfo, id: number) => {
  return http.request('put', `/api/file-info/${id}`, {
    data
  })
}

export const deleteFileInfo = (id: any) => {
  return http.request('delete', `/api/file-info/${id}`)
}
